package com.taoshen.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.NumberUtil;
import com.taoshen.entity.Location;
import com.taoshen.vo.LocationVO;
import lombok.NonNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.*;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.NearQuery;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;

/**
 * @Description
 * @Author Zhang Litao
 * @Date 2021/11/11 10:58
 */
@RestController
@RequestMapping("mongo")
public class MongoController {
    Logger log = LoggerFactory.getLogger(MongoController.class);

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 参考文献
     * https://blog.csdn.net/zhanglf02/article/details/103204354/?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_title~default-0.no_search_link&spm=1001.2101.3001.4242.1
     *
     * 初始数据：见location.js
     */


    /**
     * 获取所有附近所有的坐标记录 并且计算出距离
     * 经度 longitude
     * 纬度 latitude
     */
    @GetMapping("findAllLocation")
    public Map<String, Object> findAllLocation(@RequestParam("longitude") Double longitude,
                                               @RequestParam("latitude") Double latitude) {
        Map<String, Object> map = MapUtil.newHashMap();

        // 获取距离查询类对象
        NearQuery nearQuery = NearQuery.near(longitude, latitude);
        GeoResults<Location> geoResults = mongoTemplate.geoNear(nearQuery, Location.class);

        if (CollUtil.isEmpty(geoResults.getContent())) {
            map.put("msg", "查询数据为空");
            map.put("code", 200);
            return map;
        }

        List<LocationVO> locationList = CollUtil.newArrayList();
        for (GeoResult<Location> geoResult : geoResults) {
            @NonNull Location content = geoResult.getContent();

            LocationVO locationVO = BeanUtil.copyProperties(content, LocationVO.class);

            double v = geoResult.getDistance().getValue() * 100;
            locationVO.setDistance(NumberUtil.roundStr(v, 3) + "km");
            locationList.add(locationVO);
        }

        map.put("msg","查询成功");
        map.put("code", 200);
        map.put("count", geoResults.getContent().size());
        map.put("data", locationList);
        return map;
    }

    /**
     * 获取给定位置附近一定距离的用户
     */
    @GetMapping("findNearLocation")
    public Map<String, Object> findNearLocation(@RequestParam("longitude") Double longitude,
                                                @RequestParam("latitude") Double latitude,
                                                @RequestParam("distance") Double distance) {
        Map<String, Object> map = MapUtil.newHashMap();

        // 位置 经纬度
        Point point = new Point(longitude, latitude);

        /**
         * 计算距离时 默认单位为km 传递参数为m 所以要除以1000 设置单位为km
         */
        NearQuery query = NearQuery
                .near(point)
//                .maxDistance(new Distance(distance / 1000, Metrics.KILOMETERS));
                .maxDistance(distance / 1000, Metrics.KILOMETERS);

        GeoResults<Location> geoResults = mongoTemplate.geoNear(query, Location.class);

        if (CollUtil.isEmpty(geoResults.getContent())) {
            map.put("msg", "查询数据为空");
            map.put("code", 200);
            return map;
        }

        List<LocationVO> locationList = CollUtil.newArrayList();
        for (GeoResult<Location> geoResult : geoResults) {
            @NonNull Location content = geoResult.getContent();

            LocationVO locationVO = BeanUtil.copyProperties(content, LocationVO.class);

            double v = geoResult.getDistance().getValue();
            locationVO.setDistance(NumberUtil.roundStr(v, 3) + "km");
            locationList.add(locationVO);
        }

        map.put("msg","查询成功");
        map.put("code", 200);
        map.put("count", geoResults.getContent().size());
        map.put("data", locationList);
        return map;
    }
}
